package com.mrd.modules.quartz.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mrd.base.utils.PageUtils;
import com.mrd.base.utils.Query;
import com.mrd.base.utils.R;
import com.mrd.schedule.ConsoleManager;
import com.mrd.schedule.core.TaskDefine;


/**
 * 任务调度
 * 
 * @author han
 * @date 2017-09-22 10:39:39
 */
@RestController
@RequestMapping("sysjob")
public class SysJobController {
  @Autowired
  private SysJobService sysJobService;
  @Autowired
  SchedulerFactoryBean schedulerFactoryBean;

  /**
   * 列表
   */
  @RequestMapping("/list")
  public R list(@ModelAttribute SysJobEntity sysJob, @RequestParam Map<String, Object> params)
      throws Exception {
    // 查询列表数据
    Query query = new Query(params);
    PageHelper.startPage(query.getPage(), query.getLimit());
    List<SysJobEntity> sysJobList = sysJobService.queryListByEntity(sysJob);
    for (SysJobEntity job : sysJobList) {
      job.setRunningStatus(check(job));
    }
    PageInfo<SysJobEntity> pi = new PageInfo<SysJobEntity>(sysJobList);
    PageUtils pageUtil = new PageUtils(sysJobList, Integer.parseInt(pi.getTotal() + ""),
        query.getLimit(), query.getPage());
    return R.ok().put("page", pageUtil);
  }


  /**
   * 信息
   */
  @RequestMapping("/info/{jobId}")
  public R info(@PathVariable("jobId") Integer jobId) {
    SysJobEntity sysJob = sysJobService.queryObject(jobId);
    return R.ok().put("sysJob", sysJob);
  }

  /**
   * 保存
   */
  @RequestMapping("/save")
  public R save(@ModelAttribute SysJobEntity sysJob) {
    sysJobService.save(sysJob);
    return R.ok();
  }

  /**
   * 修改
   */
  @RequestMapping("/update")
  public R update(@ModelAttribute SysJobEntity sysJob) {
    sysJobService.update(sysJob);
    return R.ok();
  }

  /**
   * 删除
   */
  @RequestMapping("/delete")
  public R delete(@RequestBody Integer[] jobIds) {
    sysJobService.deleteBatch(jobIds);
    return R.ok();
  }

  @ResponseBody
  @RequestMapping("/check")
  public String check(SysJobEntity job) throws Exception {
    int stateInt = 0;
    String stateStr = "";
    Scheduler scheduler = schedulerFactoryBean.getScheduler();
    TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
    stateInt = scheduler.getTriggerState(triggerKey).ordinal();
    switch (stateInt) {
      case 5:
        stateStr = "BLOCKED";
        break;
      case 4:
        stateStr = "ERROR";
        break;
      case 3:
        stateStr = "COMPLETE";
        break;
      case 2:
        stateStr = "PAUSED";
        break;
      case 1:
        stateStr = "NORMAL";
        break;
      case 0:
        stateStr = "NONE";
        break;
    }
    return stateStr;
  }

  /**
   * 暂停
   * 
   * @param job
   * @return
   */
  @ResponseBody
  @RequestMapping("/pouse")
  public R pouse(SysJobEntity job) {
    try {
      Scheduler scheduler = schedulerFactoryBean.getScheduler();
      JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
      scheduler.pauseJob(jobKey);
      return R.ok();
    } catch (SchedulerException ex) {
      return R.error(ex.getMessage());
    }
  }

  /**
   * 恢复
   * 
   * @param job
   * @return
   */
  @ResponseBody
  @RequestMapping("/recover")
  public R recover(SysJobEntity job) {
    try {
      Scheduler scheduler = schedulerFactoryBean.getScheduler();
      JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
      scheduler.resumeJob(jobKey);
      return R.ok();
    } catch (SchedulerException ex) {
      return R.error(ex.getMessage());
    }
  }

  /**
   * 取消
   * 
   * @param job
   * @return
   */
  @ResponseBody
  @RequestMapping("/cancle")
  public R cancle(SysJobEntity job) {
    try {
      Scheduler scheduler = schedulerFactoryBean.getScheduler();
      TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
      scheduler.unscheduleJob(triggerKey);
      return R.ok();
    } catch (SchedulerException ex) {
      return R.error(ex.getMessage());
    }
  }

  /**
   * 运行一次,方便调试
   * 
   * @author han
   */
  @ResponseBody
  @RequestMapping("/runOneTime")
  public R runOneTime(SysJobEntity job) {
    try {
      Scheduler scheduler = schedulerFactoryBean.getScheduler();
      String jobRadomName = RandomStringUtils.random(8);
      // 不存在，创建一个
      Class jobClass = Class.forName(job.getBeanClass());
      JobDetail jobDetail = JobBuilder.newJob(jobClass)
          .withIdentity(job.getJobName() + jobRadomName, job.getJobGroup()).build();
      jobDetail.getJobDataMap().put("scheduleJob", job);

      SimpleTrigger trigger = TriggerBuilder.newTrigger()
          .withIdentity(job.getJobName() + jobRadomName, job.getJobGroup())
          .withSchedule(
              SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).withRepeatCount(0))
          .build();
      scheduler.scheduleJob(jobDetail, trigger);

      return R.ok();
    } catch (Exception ex) {
      return R.error(ex.getMessage());
    }
  }

  /**
   * 更新job时间表达式
   * 
   * @param scheduleJob
   * @throws SchedulerException
   */
  @ResponseBody
  @RequestMapping("/updateJobCron")
  public R updateJobCron(SysJobEntity scheduleJob) {
    try {
      Scheduler scheduler = schedulerFactoryBean.getScheduler();
      TriggerKey triggerKey =
          TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup());
      CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
      CronScheduleBuilder scheduleBuilder =
          CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression());
      trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder)
          .build();
      scheduler.rescheduleJob(triggerKey, trigger);
      return R.ok();
    } catch (Exception ex) {
      return R.error(ex.getMessage());
    }
  }

  @ResponseBody
  @RequestMapping("/push")
  public R push(SysJobEntity sysJob) {
    try {

      TaskDefine taskDefine = new TaskDefine();
      taskDefine.setTargetBean(sysJob.getJobName());
      taskDefine.setTargetMethod(sysJob.getBeanClass());
      taskDefine.setType(TaskDefine.TYPE_UNCODE_TASK);
      String cronExpression = sysJob.getCronExpression();
      if (StringUtils.isNotEmpty(cronExpression)) {
        taskDefine.setCronExpression(cronExpression);
      }
      taskDefine.setPeriod(0);
      taskDefine.setStartTime(new Date());
      if (StringUtils.isNotEmpty(cronExpression)) {
        ConsoleManager.addScheduleTask(taskDefine);
      }
      return R.ok();
    } catch (Exception ex) {
      return R.error(ex.getMessage());
    }
  }

}
